package com.social.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.social.dao.ComplaintDao;
import com.social.pojo.Complaint;
import com.social.pojo.Result;
import com.social.pojo.SysUser;
import com.social.pojo.dto.UserDTO;
import com.social.pojo.vto.ComplaintVTO;
import com.social.service.ComplaintService;
import com.social.service.SysUserService;
import com.social.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.social.constant.MessageConstant.*;
import static com.social.constant.RedisConstants.*;

/**
 * @Author: XiaoXu
 * @Description:
 * @Date: Created in 13:22 2022/9/29
 * @Modified By:
 * @Version: 1.0
 */

@Service
public class ComplaintServiceImpl extends ServiceImpl<ComplaintDao, Complaint> implements ComplaintService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private ComplaintDao complaintDao;

    @Resource
    private SysUserService sysUserService;

    @Override
    public Result insert(Complaint complaint) {
        /**
            * @Description 保存投诉信息
        */
        complaint.setTime(LocalDateTime.now());
        complaint.setUserId(UserHolder.getUser().getId());
        complaint.setState(0);
        boolean isSave = save(complaint);

        if(!isSave){
            return Result.fail(SAVA_DATA_FAIL,"插入失败");
        }
        stringRedisTemplate.delete(COMPLAINT_USER_KEY+complaint.getUserId());
        return Result.ok(OPERATE_DATA_SUCCESS);
    }

    @Override
    public Result getComplaintById(Long id) {
        /**
            * 通过id查询complaint信息
        */
        String key =  COMPLAINT_ID_KEY + id;

        String Json = stringRedisTemplate.opsForValue().get(key);
        if(Json != null){
            return  Result.ok(OPERATE_DATA_SUCCESS,JSONUtil.toBean(Json, Complaint.class));
        }
        Complaint complaint = getById(id);

        if(complaint == null){
            return Result.fail(QUERY_DATA_FAIL,"投诉信息不存在");
        }

        String complaintJson = JSONUtil.toJsonStr(complaint);
        stringRedisTemplate.opsForValue().set(key,complaintJson,COMPLAINT_ID_TTL, TimeUnit.MINUTES);
        return Result.ok(OPERATE_DATA_SUCCESS,complaint);
    }

    @Override
    public Result updateComplaint(Complaint complaint) {
        Complaint ids = getById(complaint.getId());
        if(ids == null){
            return Result.fail(201,"投诉信息不存在");
        }

        boolean idUpdate = updateById(complaint);

        if(!idUpdate){
            return Result.fail(201,"更新失败");
        }

        String key = COMPLAINT_ID_KEY + complaint.getId();

        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(complaint),COMPLAINT_ID_TTL,TimeUnit.MINUTES);
        return Result.ok(200);
    }

    @Override
    public Result getComplainList(Integer size ,Integer index) {

        QueryWrapper<Complaint> wrapper = Wrappers.query();
        wrapper.ne("state",2);
        IPage<Complaint> page = complaintDao.selectPage(new Page<>(index,size), wrapper);
        List<Complaint> list = page.getRecords()
                .stream()
                .map(complaint -> user(complaint))
                .collect(Collectors.toList());
        if(list == null){
            return Result.fail(201,"不存在投诉信息");
        }
        return Result.ok(200,list);
    }

    private Complaint user(Complaint complaint) {
        SysUser user = sysUserService.query().eq("id", complaint.getUserId()).one();
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        complaint.setUser(userDTO);
        return complaint;
    }

    @Override
    public Result getComplaintByUserId() {

        //查询条件
        String json = stringRedisTemplate.opsForValue().get(COMPLAINT_USER_KEY + UserHolder.getUser().getId());
        if (json != null){
            List<Complaint> list = JSONUtil.toList(json, Complaint.class);
            return Result.ok(OPERATE_DATA_SUCCESS,list);
        }

        //分页条件
        List<Complaint> list = query().eq("userId", UserHolder.getUser().getId()).list();

        if(list == null) {
            return Result.fail(201,"该用户没有投诉信息");
        }
        stringRedisTemplate.opsForValue().set(COMPLAINT_USER_KEY+UserHolder.getUser().getId(),JSONUtil.toJsonStr(list),COMPLAINT_USER_TTL,TimeUnit.MINUTES);
        return Result.ok(200,list);
    }

    @Override
    public Result getComplaintByCondition(ComplaintVTO complaintVTO) {

        QueryWrapper<Complaint> wrapper = Wrappers.query();
        wrapper.ne("state",2);
        if(StrUtil.isNotBlank(complaintVTO.getCategory())){
            wrapper.eq("category",complaintVTO.getCategory());
        }

        if(StrUtil.isNotBlank(complaintVTO.getObject())){
            wrapper.eq("object",complaintVTO.getObject());
        }

        if(complaintVTO.getBegin() != null){
            wrapper.ge("time",complaintVTO.getBegin());
        }

        if(complaintVTO.getEnd() != null) {
            wrapper.le("time",complaintVTO.getEnd());
        }

        IPage<Complaint> page = complaintDao.selectPage(new Page<>(complaintVTO.getPageIndex(), complaintVTO.getPageSize()), wrapper);
        List<Complaint> list = page.getRecords();

        if(list == null){
            return Result.fail(201,"不存在数据");
        }

        return Result.ok(200,list);
    }

    @Override
    public Result dealComplaint(Long id) {
        boolean isSuccess = update().eq("id", id).setSql("state = 1").update();
        if (!isSuccess){
            Result.fail(OPERATE_DATA_FAIL,"操作失败");
        }
        return Result.ok(OPERATE_DATA_SUCCESS);
    }

}
